<template>
  <div class="app-container wh100">
    <el-row :gutter="20" class="wh100">
      <el-col :span="4" :xs="24">
        <el-input v-model="filterText" placeholder="输入名称搜索" clearable />
        <el-tree
          ref="tree"
          v-loading="loadingTree"
          class="mt5"
          empty-text="无数据"
          :data="tree"
          :filter-node-method="filterNode"
          :expand-on-click-node="false"
          highlight-current
          node-key="orgId"
          :default-expanded-keys="[1,-10,-11]"
          :current-node-key="orgId"
          :props="defaultProps"
          @node-click="handleNodeClick"
        >
          <span slot-scope="{ node, data }" class="custom-tree-node">
            <span>
              <i :class="data.iconClass" />{{ data.orgName }}
            </span>
          </span>
        </el-tree>
      </el-col>
      <el-col :span="20" :xs="24">
        <el-row :gutter="20">
          <el-col :span="24" class="solid-bottom">
            <el-popover placement="bottom" title="说明" trigger="hover">
              <i slot="reference" class="el-icon-info icon-help"></i>
              <p class="font-12">
                <b class="m5 inline-block main-color">蓝色</b>为自有权限<br>
                <b class="m5 inline-block black">黑色</b>为继承权限<br>
                <b class="m5 inline-block red">红色</b>为拒绝权限<br>
              </p>
            </el-popover>
            <el-button
              size="small"
              type="primary"
              plain
              :loading="savingRight"
              class="m5"
              icon="iconfont icon-baocunwendang"
              :disabled="!canSaveR"
              @click="saveRight"
            >保 存</el-button>
            <el-button
              size="small"
              type="danger"
              plain
              class="m5"
              :loading="clearSelf"
              icon="el-icon-circle-close"
              :disabled="orgId<=0"
              @click="clearSelfRight"
            >清空权限</el-button>
            <el-button
              type="primary"
              plain
              class="m5"
              icon="el-icon-sort"
              size="mini"
              @click="toggleExpandAll"
            >展开/折叠</el-button>
            <el-input v-model="filterMenu" placeholder="输入名称搜索" clearable class="w250 ml10 m5" />
          </el-col>
          <el-col :span="24" class="p0 pl10 pr10 auth-board" v-loading="loadingMenu">
            <el-collapse :value="collValue">
              <el-collapse-item :name="'menu_'+menu.menuId" v-for="(menu,i) in right" :key="menu.menuId">
                <template slot="title"><b>{{ menu.menuName }}</b></template>
                <div class="flex-row">
                  <div class="second-box">
                    <div class="w100">
                      <el-checkbox :disabled="menu.disabled || !canClick" @change="clickBox(menu)" :indeterminate="menu.clickNum===2" v-model="menu.checked" :class="{self:menu.self}">
                        <i :class="menuTypeIconMap[menu.menuType]"></i>{{ menu.menuName }}
                      </el-checkbox>
                    </div>
                    <div class="landscape" v-for="(child,j) in menu.children" :key="'child'+j">
                      <div class="over">
                        <el-checkbox :disabled="child.disabled || !canClick" @change="clickBox(child)" :indeterminate="child.clickNum===2" v-model="child.checked" :class="{self:child.self}">
                          <i :class="menuTypeIconMap[child.menuType]"></i>{{ child.menuName }}
                        </el-checkbox>
                        <div class="landscape" v-for="(third,k) in child.children" style="text-indent: 1em" :key="'third'+k">
                          <div class="over">
                            <el-checkbox :disabled="third.disabled || !canClick" @change="clickBox(third)" :indeterminate="third.clickNum===2" v-model="third.checked" :class="{self:third.self}">
                              <i :class="menuTypeIconMap[third.menuType]"></i>{{ third.menuName }}
                            </el-checkbox>
                            <div class="landscape" v-for="(four,l) in third.children" style="text-indent: 1.5em" :key="'four'+l">
                              <div class="over">
                                <el-checkbox :disabled="four.disabled || !canClick" @change="clickBox(four)" :indeterminate="four.clickNum===2" v-model="four.checked" :class="{self:four.self}">
                                  <i :class="menuTypeIconMap[four.menuType]"></i>{{ four.menuName }}
                                </el-checkbox>
                              </div>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </el-collapse-item>
            </el-collapse>

          </el-col>
        </el-row>
      </el-col>
    </el-row>
    <el-backtop target=".app-wrapper"></el-backtop>
  </div>

</template>

<script>

import { clearSelfRight, rightData, saveTreeRight } from '@/api/right'
import { fullTree } from '@/api/org'
import { Mixin } from '@/utils/mixin'
export default {
  name: 'MenuRight',
  mixins: [Mixin],
  data() {
    return {
      tree: [],
      right: [],
      beforeList: [],
      afterList: [],
      collValue: [],
      loadingTree: false,
      loadingMenu: false,
      clearSelf: false,
      savingRight: false,
      orgId: 0,
      coll: [],
      defaultProps: {
        children: 'childs',
        label: 'orgName'
      },
      menuProps: {
        children: 'children',
        label: 'menuName'
      },
      filterText: '',
      filterMenu: ''
    }
  },
  computed: {
    canClick() {
      return this.orgId > 1
    },
    canSaveR() {
      return this.orgId > 1 && this.canSave()
    }
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val)
    },
    filterMenu(val) {
      this.$refs.menu.filter(val)
    }
  },
  mounted() {
    this.initTree()
  },
  methods: {
    saveRight() {
      const par = this.getChangePar()
      this.savingRight = true
      saveTreeRight(par).then(() => {
        this.$message.success('保存成功')
        this.savingRight = false
        this.loadRightData(this.orgId)
      }).catch(()=>{})
    },
    /** 展开/折叠操作 */
    toggleExpandAll() {
      if(this.collValue.length > 0){
        this.collValue = []
      }else{
        this.collValue = this.beforeList.map(p => 'menu_' + p.menuId)
      }
    },
    clearSelfRight() {
      this.$confirm('是否要清除自身权限？继承的权限不会受影响', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.clearSelf = true
        const par = { orgId: this.orgId, rightKey: 'MENU_RIGHT', rightType: 'YES' }
        clearSelfRight([par]).then(() => {
          this.$message.success('操作成功')
          this.clearSelf = false
          this.loadRightData(this.orgId)
        })
      }).catch(()=>{})
    },
    clickBox(data) {
      const _this = this
      let clickNum = data.clickNum
      let mod = 0
      let val = clickNum + 1
      mod = val % 3
      if (mod === 0) {
        data.checked = false
      } else if (mod === 1) {
        data.checked = true
      } else {
        data.checked = false
      }
      data.clickNum = mod
      console.log(data.clickNum)
      const isChecked = data.checked
      // 如果当前节点被选中，则遍历上级节点和下级子节点并选中，如果当前节点取消选中，则遍历下级节点并取消选中
      if (isChecked) {
        // 判断是否有上级节点，如果有那么遍历设置上级节点选中
        data.parentId && setParentChecked(data.parentId)
      }
      // 判断该节点是否有下级节点，如果有那么遍历设置下级节点clickNum
      data.children && setChildrenClickNum(data.children, mod,data.checked)
      function setParentChecked(parentId) {
        // 获取该id的父级node
        const parentNode = _this.findMenuById(_this.right,parentId)
        if(parentNode){
          // 如果该id的父级node存在父级id则继续遍历
          parentNode.parentId && setParentChecked(parentNode.parentId)
          if(parentNode.disabled!==true){
            parentNode.checked = true
            parentNode.clickNum = 1
          }
        }
      }
      function setChildrenClickNum(node, clickNum, checked) {
        node.forEach(item => {
          item.children && setChildrenClickNum(item.children, clickNum, checked)
          if(item.disabled !== true){
            item.clickNum = clickNum
            item.checked = checked
          }
        })
      }
    },
    findMenuById(list,id){
      for (let i = 0; i < list.length; i++) {
        if(list[i].menuId===id){
          return list[i]
        }else if(list[i].children){
          let v = this.findMenuById(list[i].children,id)
          if(v != null){
            return v
          }
        }
      }
      return null
    },
    canSave() {
      const l1 = this.beforeList
      const l2 = this.afterList
      for (let i = 0; i < l1.length; i++) {
        //console.log(l1[i].menuName,l1[i].clickNum,l1[2].menuName,l1[2].clickNum)
        if (l1[i].clickNum !== l2[i].clickNum) {
          return true
        }
      }
      return false
    },
    getChangePar() {
      const l1 = this.beforeList
      const l2 = this.afterList
      const par = { orgId: this.orgId, rightKey: 'MENU_RIGHT', rightType: 'YES' }
      const changeNode = []

      for (let i = 0; i < l1.length; i++) {
        if (l1[i].clickNum !== l2[i].clickNum) {
          changeNode.push({ id: l2[i].menuId, clickNum: l2[i].clickNum })
        }
      }
      par.changeNode = changeNode
      return [par]
    },
    initTree() {
      this.loadingTree = true
      fullTree().then((res) => {
        const l = res.data
        this.tree = l
        this.loadingTree = false

        this.loadRightData(0)
      }).catch(() => {
        this.loadingTree = false
      })
    },
    toList(list,l){
      for (let i = 0; i < list.length; i++) {
        l.push(list[i])
        if(list[i].children){
          this.toList(list[i].children,l)
        }
      }
    },
    loadRightData(orgId) {
      this.loadingMenu = true
      rightData({ orgId: orgId }).then((res) => {
        this.right = res.data.right
        this.toList(this.right,this.afterList)
        this.beforeList = this.$util.copy(this.afterList)
        if(this.collValue.length === 0){
          this.collValue = this.beforeList.map(p=> 'menu_' + p.menuId)
        }
        this.loadingMenu = false
        if (this.filterMenu) {
          this.$nextTick(() => {
            this.$refs.menu.filter(this.filterMenu)
          })
        }
      }).catch(() => {
        this.loadingMenu = false
      })
    },
    handleNodeClick(e) {
      if (e.orgId > 1) {
        this.orgId = e.orgId
        this.loadRightData(this.orgId)
      } else {
        this.$nextTick(() => {
          this.$refs.tree.setCurrentKey(this.orgId)
        })
      }
    },
    logMenu(e) {
      console.log(e)
    },
    filterNode(value, data) {
      if (!value) return true
      return data.orgName.indexOf(value) !== -1
    },
    filterMenuNode(value, data) {
      if (!value) return true
      return data.menuName.indexOf(value) !== -1
    }
  }
}
</script>
<style scoped lang="scss">
.second-box{
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
  .landscape{
    text-indent: 0.5em;
    width: 220px;
    float: left;
    word-break: break-all;
    display: inline-block;
    .over{
      width: 250px;
      i{
        text-indent: -0.5em;
      }
    }
  }
}


::v-deep .auth-board .el-checkbox{
  .el-checkbox__label {
    padding-left: 3px;
    color: var(--textcolor);
  }
  &.self{
    .el-checkbox__label{
      color: var(--maincolor);
    }
  }
  .is-indeterminate{
    .el-checkbox__inner{
      background-color: var(--redcolor);
      border-color: var(--redcolor);
    }
  }
}
</style>
